#include "audioencodetask.h"
#include <qDebug>
#include <dlfcn.h> /* 必须加这个头文件 */
AudioEncodeTask::AudioEncodeTask(Receive_handler *pHandler):m_pHandler(pHandler)
{

    outfile = NULL;

    pSo_handler = dlopen("libfaac.so", RTLD_NOW);

    pfaacEncOpen = (faacEncHandle (*)(unsigned long sampleRate,
                                      unsigned int numChannels,
                                      unsigned long *inputSamples,
                                      unsigned long *maxOutputBytes))dlsym(pSo_handler, "faacEncOpen");

    pfaacEncGetCurrentConfiguration = (faacEncConfigurationPtr (*)(faacEncHandle hEncoder))dlsym(pSo_handler, "faacEncGetCurrentConfiguration");

    pfaacEncSetConfiguration= (int (*)(faacEncHandle hEncoder,faacEncConfigurationPtr config))dlsym(pSo_handler, "faacEncSetConfiguration");

    pfaacEncClose= (int (*)(faacEncHandle hEncoder))dlsym(pSo_handler, "faacEncClose");

    pfaacEncEncode= (int (*)(faacEncHandle hEncoder, int32_t * inputBuffer,
                             unsigned int samplesInput,unsigned char *outputBuffer,
                             unsigned int bufferSize))dlsym(pSo_handler, "faacEncEncode");


    qDebug(QString("dlopen:").append(QString::number((long)pSo_handler)).toLocal8Bit().data());
    qDebug(QString("pfaacEncOpen:").append(QString::number((long)pfaacEncOpen)).toLocal8Bit().data());

    qDebug(QString("pfaacEncGetCurrentConfiguration:").append(QString::number((long)pfaacEncGetCurrentConfiguration)).toLocal8Bit().data());
    qDebug(QString("pfaacEncSetConfiguration:").append(QString::number((long)pfaacEncSetConfiguration)).toLocal8Bit().data());
    qDebug(QString("pfaacEncClose:").append(QString::number((long)pfaacEncClose)).toLocal8Bit().data());
    qDebug(QString("pfaacEncEncode:").append(QString::number((long)pfaacEncEncode)).toLocal8Bit().data());

    unsigned long nSampleRate = 8000;  // 采样率
    unsigned int nChannels = 1;         // 声道数

    nPCMBitSize = 16;      // 单样本位数

    nInputSamples = 0;

    nMaxOutputBytes = 0;

    hEncoder = pfaacEncOpen(nSampleRate, nChannels, &nInputSamples, &nMaxOutputBytes);

    if(hEncoder == NULL)
    {
        qDebug(QString("[ERROR] Failed to call faacEncOpen()").toLocal8Bit().data());
        return  ;
    }

    nPCMBufferSize = nInputSamples * nPCMBitSize / 8;

    qDebug(QString("nPCMBufferSize size:").append(QString::number((long)nPCMBufferSize)).toLocal8Bit().data());
    qDebug(QString("nMaxOutputBytes size:").append(QString::number((long)nMaxOutputBytes)).toLocal8Bit().data());

    pbPCMBuffer = new unsigned char [nPCMBufferSize]; //输入PCM buf长度

    pbAACBuffer = new unsigned char [nMaxOutputBytes];//输出AAC buf长度

    pConfiguration = pfaacEncGetCurrentConfiguration(hEncoder);

    pConfiguration->inputFormat = FAAC_INPUT_16BIT;
    pConfiguration->aacObjectType = LOW;

    int nRet = pfaacEncSetConfiguration(hEncoder, pConfiguration);
    if(nRet)
    {
        char aacFileName[100]={0};
        sprintf(aacFileName,"/sdcard/test3.aac");//  /storage/sdcard0/new23.aac

//        outfile = fopen(aacFileName, "wb");
    }

    m_pack_num1 = 0;
    m_pack_num2 = 0;
}

AudioEncodeTask::~AudioEncodeTask()
{
    pfaacEncClose(hEncoder);

    dlclose(pSo_handler);

//    if(outfile)
//        fclose(outfile);

    delete []pbPCMBuffer;

    delete []pbAACBuffer;
}

int AudioEncodeTask::close()
{
    std::string str("");

    int nthread  =thr_count();

    for (int i =0 ;i<nthread ;i++)
        putq(str);

    wait();
    return 0;
}

bool AudioEncodeTask::receive_handler(char *data, int size)
{
    m_pack_num1 ++ ;
    //qDebug(QString("AudioEncodeTask::receive_handler size:").append(QString::number((long)size)).toLocal8Bit().data());
    putq(std::string(data,size));
    return true;
}

int AudioEncodeTask::svc()
{
    std::string str ="";

     while(getq(str))
     {
         if (str=="")
            break;

         m_pack_num2 ++;

         int data_size = str.length();

         if(nPCMBufferSize == data_size)
         {
             memset(pbPCMBuffer,0,nPCMBufferSize);

             memcpy(pbPCMBuffer,str.data(),data_size);

             int nInputs = data_size / (nPCMBitSize / 8);

             //qDebug(QString("nInputs size:").append(QString::number((long)nInputs)).toLocal8Bit().data());

             int nRetLength = pfaacEncEncode(hEncoder, (int*) pbPCMBuffer, nInputs, pbAACBuffer, nMaxOutputBytes);

//             QString strInfo;
//             strInfo.sprintf("pack_num1: %d  pack_num2:%d ",m_pack_num1,m_pack_num2);
//             qDebug(strInfo.toLocal8Bit().data());

             //qDebug(QString("nRetLength size:").append(QString::number((long)nRetLength)).toLocal8Bit().data());
             if(m_pHandler)
                 m_pHandler->receive_handler((char*)pbAACBuffer,nRetLength);//发送到网络

//             if(outfile)
//                fwrite(pbAACBuffer, 1, nRetLength, outfile);
         }
     }
     return 0;
}

